<template>
  <div class="app-container">
    <header>
      <h1>🎯 Vue 3 响应式基础学习</h1>
      <p class="subtitle">使用组合式 API + TypeScript</p>
    </header>

    <main>
      <!-- 示例 1: ref() 基础 -->
      <section class="example-card">
        <h2>📦 示例 1: ref() - 响应式基本类型</h2>
        <div class="example-content">
          <p>计数器值: {{ counter }}</p>
          <button @click="increment" class="btn">+1</button>
          <button @click="decrement" class="btn">-1</button>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> ref() 用于创建响应式的基本类型数据。访问值时需要使用 .value (在脚本中)。</p>
        </div>
      </section>

      <!-- 示例 2: reactive() 基础 -->
      <section class="example-card">
        <h2>🏠 示例 2: reactive() - 响应式对象</h2>
        <div class="example-content">
          <p>用户信息:</p>
          <div class="user-info">
            <p>姓名: {{ user.name }}</p>
            <p>年龄: {{ user.age }}</p>
          </div>
          <button @click="updateUser" class="btn">更新用户</button>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> reactive() 用于创建响应式对象。对于复杂数据结构，reactive() 更自然。</p>
        </div>
      </section>

      <!-- 示例 3: ref vs reactive -->
      <section class="example-card">
        <h2>⚖️ 示例 3: ref vs reactive 对比</h2>
        <div class="example-content">
          <div class="comparison">
            <div class="comparison-item">
              <h3>ref 版本</h3>
              <p>商品价格: {{ productPrice }}</p>
              <button @click="updateProductPrice" class="btn">涨价</button>
            </div>
            <div class="comparison-item">
              <h3>reactive 版本</h3>
              <p>商品价格: {{ product.price }}</p>
              <button @click="updateProduct" class="btn">涨价</button>
            </div>
          </div>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> ref 适合基本类型，reactive 适合对象。两者都能实现响应式，但使用场景略有不同。</p>
        </div>
      </section>

      <!-- 示例 4: computed -->
      <section class="example-card">
        <h2>🧮 示例 4: computed() - 计算属性</h2>
        <div class="example-content">
          <p>原始价格: ¥{{ price }}</p>
          <p>折扣: {{ discount }}%</p>
          <p class="highlight">折后价格: ¥{{ discountedPrice }}</p>
          <button @click="changePrice" class="btn">更改价格</button>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> computed() 创建计算属性，会缓存结果，只有依赖项变化时才重新计算。</p>
        </div>
      </section>

      <!-- 示例 5: watch -->
      <section class="example-card">
        <h2>👀 示例 5: watch() - 侦听器</h2>
        <div class="example-content">
          <p>输入消息: <input v-model="message" class="input" /></p>
          <p class="highlight" v-if="lastUpdated">上次更新: {{ lastUpdated }}</p>
          <p class="highlight" v-if="messageCount > 0">已修改 {{ messageCount }} 次</p>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> watch() 用于侦听数据变化，可以执行副作用操作。</p>
        </div>
      </section>

      <!-- 示例 6: watchEffect -->
      <section class="example-card">
        <h2>✨ 示例 6: watchEffect() - 自动依赖跟踪</h2>
        <div class="example-content">
          <p>用户名: <input v-model="username" class="input" /></p>
          <p>密码: <input v-model="password" class="input" type="password" /></p>
          <p class="highlight" v-if="validationMessage">{{ validationMessage }}</p>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> watchEffect() 自动跟踪其内部使用的响应式数据，无需手动指定依赖。</p>
        </div>
      </section>

      <!-- 示例 7: 响应式数组 -->
      <section class="example-card">
        <h2>📋 示例 7: 响应式数组操作</h2>
        <div class="example-content">
          <div class="todo-app">
            <input v-model="newTodo" @keyup.enter="addTodo" class="input" placeholder="添加待办事项" />
            <button @click="addTodo" class="btn">添加</button>
            <ul class="todo-list">
              <li v-for="(todo, index) in todos" :key="index">
                {{ todo }}
                <button @click="removeTodo(index)" class="btn btn-small">删除</button>
              </li>
            </ul>
            <p v-if="todos.length === 0">暂无待办事项</p>
          </div>
        </div>
        <div class="explanation">
          <p><strong>📝 说明:</strong> ref() 和 reactive() 都可以创建响应式数组，支持 push、pop 等操作。</p>
        </div>
      </section>
    </main>

    <footer>
      <p>🎓 Vue 3 响应式基础学习教程 © {{ new Date().getFullYear() }}</p>
    </footer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, watchEffect, onMounted } from 'vue'

// 示例 1: ref() 基础
const counter = ref(0)

const increment = () => {
  counter.value++
}

const decrement = () => {
  counter.value--
}

// 示例 2: reactive() 基础
interface User {
  name: string
  age: number
}

const user = reactive<User>({
  name: '张三',
  age: 25
})

const updateUser = () => {
  user.name = '李四'
  user.age = 26
}

// 示例 3: ref vs reactive 对比
const productPrice = ref(99)
const product = reactive({ price: 99 })

const updateProductPrice = () => {
  productPrice.value += 10
}

const updateProduct = () => {
  product.price += 10
}

// 示例 4: computed()
const price = ref(100)
const discount = ref(20)

const discountedPrice = computed(() => {
  console.log('计算折后价格...')
  return price.value * (1 - discount.value / 100)
})

const changePrice = () => {
  price.value = Math.floor(Math.random() * 100) + 50
}

// 示例 5: watch()
const message = ref('')
const lastUpdated = ref('')
const messageCount = ref(0)

watch(message, (newValue, oldValue) => {
  lastUpdated.value = new Date().toLocaleTimeString()
  messageCount.value++
  console.log(`消息从 "${oldValue}" 变为 "${newValue}"`)
})

// 示例 6: watchEffect()
const username = ref('')
const password = ref('')
const validationMessage = ref('')

watchEffect(() => {
  if (username.value && password.value) {
    if (password.value.length < 6) {
      validationMessage.value = '密码太短了！'
    } else {
      validationMessage.value = '验证通过！'
    }
  } else {
    validationMessage.value = ''
  }
})

// 示例 7: 响应式数组
const todos = ref<string[]>([])
const newTodo = ref('')

const addTodo = () => {
  if (newTodo.value.trim()) {
    todos.value.push(newTodo.value)
    newTodo.value = ''
  }
}

const removeTodo = (index: number) => {
  todos.value.splice(index, 1)
}

// 组件挂载时的一些示例初始化
onMounted(() => {
  console.log('🎉 Vue 3 响应式基础学习开始！')
})
</script>

<style scoped>
.app-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}

header {
  text-align: center;
  margin-bottom: 40px;
  padding: 20px;
  background: linear-gradient(135deg, #42b883 0%, #35495e 100%);
  color: white;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

h1 {
  margin: 0;
  font-size: 2.5rem;
}

.subtitle {
  margin: 10px 0 0 0;
  font-size: 1.2rem;
  opacity: 0.9;
}

.example-card {
  background: white;
  border-radius: 10px;
  padding: 25px;
  margin-bottom: 30px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.example-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}

h2 {
  color: #35495e;
  margin-top: 0;
  border-bottom: 2px solid #42b883;
  padding-bottom: 10px;
}

.example-content {
  padding: 20px 0;
}

.explanation {
  background: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
  border-left: 4px solid #42b883;
  margin-top: 20px;
}

.btn {
  background: #42b883;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  margin: 0 5px;
  font-size: 14px;
  transition: background 0.3s ease;
}

.btn:hover {
  background: #3aa577;
}

.btn-small {
  padding: 4px 8px;
  font-size: 12px;
  background: #ff6b6b;
}

.btn-small:hover {
  background: #ff5252;
}

.user-info {
  background: #f0f2f5;
  padding: 15px;
  border-radius: 6px;
  margin: 15px 0;
}

.comparison {
  display: flex;
  gap: 20px;
}

.comparison-item {
  flex: 1;
  background: #f0f2f5;
  padding: 15px;
  border-radius: 6px;
}

.comparison-item h3 {
  margin-top: 0;
  color: #35495e;
}

.highlight {
  background: #ffeaa7;
  padding: 10px;
  border-radius: 4px;
  font-weight: bold;
}

.input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  margin: 5px 0;
  width: 250px;
}

.todo-app {
  max-width: 500px;
}

.todo-list {
  list-style: none;
  padding: 0;
}

.todo-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: #f0f2f5;
  margin: 5px 0;
  border-radius: 4px;
}

footer {
  text-align: center;
  margin-top: 50px;
  padding: 20px;
  color: #666;
  font-size: 0.9rem;
}

@media (max-width: 768px) {
  .comparison {
    flex-direction: column;
  }
  
  .input {
    width: 100%;
    box-sizing: border-box;
  }
}
</style>